/**
 * 整合layui.table
 * 需要 layui.form layui.table layui.laypage layui.binder
 */
("use strict");
layui.define(['table'],function (exports) {
  let VM = layui.binder;
  const LAYTABLE_CONFIG = {
    elem: "",
    head: "",
    url: null,
    where: null,
    method: "post",
    loading: false,
    data: [],
    title: "",
    cellMinWidth: 120,
    text: null,
    height: "",
    cols: [],
    limit: 10,
    render: false,
    toolbarID: null,
    page: {
      groups: 3,
      layout: ["prev", "page", "next", "skip", "count"],
      jump: function jump(obj, first) {
        if (!first) {
        }
      },
    },
    done: null,
  };
  VM.Method("fitBar", function (parent, bar) {
    let eles = $(parent.find("#" + bar).html()).find(".layui-btn");
    if (eles.length == 0) return 40;
    let toolbarWidth = 40;
    _.each(eles, function (v) {
      let context = $(v).html();
      toolbarWidth += 20 + context.length * 12;
    });
    return toolbarWidth;
  });

  VM.Method("searchTable", function (flag) {
    let opt = {
      height: this.tableHeightMultiple(),
      limit: this.tableLimitMultiple(),
    };
    return flag
      ? this.renderListPage.call(this, this.page.tableFilter, null, opt)
      : this.renderListPage.call(this, this.page.tableFilter, 1, opt);
  });

  VM.Method("renderListPage", function (filter, curr, opt) {
    if (!this.verifyForm()) return false;
    if (!opt) opt = { height: this.tableHeight(), limit: this.tableLimit() };
    return reloadTable.apply(this, [
      filter || this.page.tableFilter,
      curr,
      opt,
    ]);
  });

  VM.Method("tableHead", function () {
    return layui.tool ? layui.tool.getToken() : {};
  });

  VM.Method("tableHeight", function (filter, offset) {
    try {
      let tableFilter = filter || this.page.tableFilter;
      let filterItem = this.parent.find('[lay-filter="' + tableFilter + '"]');
      let filterPos = filterItem.offset().top - this.parent.offset().top;
      let extra = offset || this.page.tableOffset;
      let totalHeight =
        this.parent.outerHeight() -
        (filterPos + extra + filterItem.outerHeight());
      return totalHeight < 480 ? 480 : totalHeight;
    } catch (error) {
      console.log("fit table error");
      return 480;
    }
  });
  VM.Method("tableLimit", function (filter, offset) {
    try {
      let tableFilter = filter || this.page.tableFilter;
      let filterItem = this.parent.find('[lay-filter="' + tableFilter + '"]');
      let filterPos = filterItem.offset().top - this.parent.offset().top;
      let extra = offset || this.page.tableOffset;
      let totalHeight =
        this.parent.outerHeight() -
        (filterPos + extra + filterItem.outerHeight());
      let tableHeight = totalHeight - 45;
      tableHeight = tableHeight < 480 ? 480 : tableHeight;
      tableHeight -= 20;
      let limit = Math.floor(tableHeight * 0.025 * 0.2) * 5;
      return limit;
    } catch (error) {
      console.log("fit table error");
      return 10;
    }
  });
  VM.Method("tableHeightMultiple", function (filter, offset, root) {
    try {
      let tableFilter = filter || this.page.tableFilter;
      let rootItem = root || this.parent;
      if (!rootItem.hasClass("layui-tab-parent"))
        rootItem = rootItem.parents().filter(".layui-tab-parent");
      let filterItem = rootItem.find('[lay-filter="' + tableFilter + '"]');
      let filterPos = filterItem.offset().top - rootItem.offset().top;
      let extra = offset || this.page.tableOffset;
      let totalHeight =
        rootItem.outerHeight() - (filterPos + extra + filterItem.outerHeight());
      return totalHeight < 480 ? 480 : totalHeight;
    } catch (error) {
      console.log("fit table error");
      return 480;
    }
  });

  VM.Method("tableLimitMultiple", function (filter, offset, root) {
    try {
      let tableFilter = filter || this.page.tableFilter;
      let rootItem = root || this.parent;
      if (!rootItem.hasClass("layui-tab-parent"))
        rootItem = rootItem.parents().filter(".layui-tab-parent");
      let filterItem = rootItem.find('[lay-filter="' + tableFilter + '"]');
      let filterPos = filterItem.offset().top - rootItem.offset().top;
      let extra = offset || this.page.tableOffset;
      let totalHeight =
        rootItem.outerHeight() - (filterPos + extra + filterItem.outerHeight());
      let tableHeight = totalHeight - 45;
      tableHeight = tableHeight < 480 ? 480 : tableHeight;
      tableHeight -= 20;
      let limit = Math.floor(tableHeight * 0.025 * 0.2) * 5;
      return limit;
    } catch (error) {
      console.log("fit table error");
      return 10;
    }
  });

  VM.Method("tableText", function (alias) {
    let _alias = alias || this.page.tableAlias;
    return {
      none: `暂无${_alias}信息！`,
      fail: `<span style = "color:blue">暂无${_alias}信息！<span>`,
      error: `<span style = "color:red">暂无${_alias}信息！<span>`,
    };
  });
  VM.diretive("table", function (element, binding) {
    let that = this;
    let instance = binding.modifiers.instance;
    if (!that.proxy.tableMap) that.proxy.tableMap = {};
    let tableFilter = instance.target.attr("lay-filter");
    if (that.proxy.tableMap[tableFilter])
      return reloadTable.call(that, tableFilter);
    let sourseStr = instance["v-table"];
    let cols = [];
    instance.target.find("col").each(function () {
      let $this = $(this);
      let align = $this.attr("lay-align");
      let type = $this.attr("type");
      let width = $this.attr("width");
      let minWidth = $this.attr("minWidth");
      let title = $this.attr("title");
      let templet = $this.attr("lay-templet");
      let field = $this.attr("lay-field");
      let bar = $this.attr("lay-bar");
      let colObject = {};
      if (align) colObject.align = align;
      if (type) colObject.type = type;
      if (width) colObject.width = Number(width);
      if (minWidth) colObject.minWidth = Number(minWidth);
      if (title) colObject.title = title;
      if (field) colObject.field = field;
      if (templet) {
        colObject.templet = function (d) {
          if (/({{[^{}]+}})/.test(templet)) {
            let tempFunctionStr = templet
              .substring(2, templet.length - 2)
              .trim();
            if (!_.startsWith(tempFunctionStr, "return "))
              tempFunctionStr = "return " + tempFunctionStr;
            if (!_.endsWith(tempFunctionStr, ";")) tempFunctionStr += ";";
            return new Function("d", tempFunctionStr).call(that, d);
          }
          let cb = that.proxy.getValue.call(that, templet);
          if (cb && _.isFunction(cb)) return cb.call(that, d);
          return "";
        };
      }
      if (/({{[^{}]+}})/.test(colObject.title)) {
        let tempTitleStr = colObject.title
          .substring(2, colObject.title.length - 2)
          .trim();
        colObject.title = that.proxy.getValue.call(that, tempTitleStr);
      }
      let realBar = "";
      if (undefined !== bar)
        realBar =
          bar.indexOf("-mirror") > 0 ? bar.substring(0, bar.length - 7) : bar;
      cols.push(
        undefined !== bar
          ? {
              fixed: "right",
              title: "操作",
              toolbar: "#" + realBar,
              width: that.fitBar(that.parent, bar),
            }
          : colObject
      );
    });
    that.proxy.tableMap[tableFilter] = {
      filter: sourseStr,
      cols: cols,
      render: false,
    };
    renderTable.call(that, instance, tableFilter);
    instance.target.removeAttr("v-table");
    instance.target.empty();
  });
  function renderTable(instance, tableFilter) {
    let that = this;
    let _tableConfig = _.cloneDeep(LAYTABLE_CONFIG);
    let cache = that.proxy.tableMap[tableFilter];
    let options = null,
      tableParam = null;
    let _list = that.proxy.monitor.call(that, function () {
      options = _.assign(
        {},
        _tableConfig,
        parseObject.call(that, that.proxy.getValue.call(that, cache.filter)),
        {
          elem: instance.target,
        }
      );
      if (options.cols.length === 0) options.cols = [cache.cols];
      let formFilter = instance.target
        .parents()
        .filter(".layui-form")
        .attr("lay-filter");
      tableParam = that.formData(formFilter);
      options.where = parseObject.call(that, tableParam);
      if (_.isFunction(options.encode))
        options.where = options.encode.call(that, options.where);
    });
    if (instance.target.attr("v-table") !== undefined)
      _.each(_list, function (value) {
        let prefix = that.config.propertychangeprefix;
        that.proxy.on.call(
          that,
          prefix + value,
          "parsetable-" + tableFilter,
          function () {
            renderTable.call(that, instance, tableFilter);
          }
        );
      });
    let _done = options.done;
    options.done = function (res, curr, count) {
      that.proxy.tableMap[tableFilter].curr = curr;
      _done && _done.apply(that, [res, curr, count]);
    };
    if (
      that.proxy.tableMap[tableFilter].options &&
      that.proxy.tableMap[tableFilter].options.render
    )
      options.render = true;
    that.proxy.tableMap[tableFilter].options = options;
    let opt = _.cloneDeep(options);
    if (!opt.render) {
      opt.url = "";
      opt.loading = true;
      opt.data = [];
    }
    tableParam && layui.table.render(opt);
  }
  function parseObject(_res) {
    let res = _.cloneDeep(_res);
    if (!res) return res;
    let that = this;
    _.each(res, function (v, k) {
      if (/({{[^{}]+}})/.test(v)) {
        let _v = that.proxy.getValue.call(
          that,
          _.trim(v.substring(2, v.length - 2))
        );
        if (_.isFunction(_v) && "done" != k && "encode" != k) {
          let value = _v.call(that);
          if (value !== undefined) res[k] = value;
        } else {
          res[k] = _v;
        }
      }
    });
    return res;
  }
  function reloadTable(filter, curr, opt) {
    let param = this.proxy.tableMap[filter].options;
    param.page.curr = curr || this.proxy.tableMap[filter].curr;
    let p = _.assign({}, param, opt);
    if (opt && opt.limit) p.page.limit = opt.limit;
    this.proxy.tableMap[filter].options = p;
    if (p.render) layui.table.reload(filter, p);
  }
  exports("vtable", {});
});
